/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package clip.model;

import L.L;
import clip.net.RMIClient;
import java.awt.datatransfer.DataFlavor;
import java.io.Serializable;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Observable;

/**
 *
 * @author admin
 */
public class Buddy extends Observable implements Serializable {
    //Konstanten
    public static enum CONNECTIONSTATUS {CONNECTING,CONNECTED,DISCONNECTED,NULL};
    
    //felder zum abspeichern
    private String nickname;
    private String hostname;
    private int port;
    
    //transiente felder
    private transient RMIClient rmiClient = null;
    private transient CONNECTIONSTATUS Status;
    private transient boolean _isConnectionAlive =false;
    
    public Buddy(String nickname, String hostname, int port) {
        this.nickname = nickname;
        this.hostname = hostname;
        this.port = port;
        connectToBuddy();
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getTestString() throws RemoteException {
        return rmiClient.getTestString();
    }
    
    public void receiveMessage(String message) throws RemoteException {
        rmiClient.getRemoteApi().receiveMessage(message);
    }
    
    

    public boolean isConnectionAlive() {
        return _isConnectionAlive;
    }
    
    public boolean checkConnectionAlive() {
        try {
            _isConnectionAlive = rmiClient.checkConnectionAlive();
        } catch (RemoteException ex) {
            L.n("RemoteException"+ex.getMessage());
            _isConnectionAlive=false;
        }
        return _isConnectionAlive;
    }

    public ClipboardSnapshot getClipboardSnapshot() throws RemoteException {
        ClipboardSnapshot cs = rmiClient.getClipboardSnapshot();
        L.o("anzahl flavors, clipsnapshot", cs.getTransferDataFlavors().length, cs.toString());
        L.s();
        for (int i = 0; i < cs.getTransferDataFlavors().length; i++) {
            DataFlavor df = cs.getTransferDataFlavors()[i];
            L.o("FLAVOR,flavors", i, df.toString());
        }
        return cs;
    }

    public void connectToBuddy() {
        this.setStatus(CONNECTIONSTATUS.CONNECTING);
        new Thread() {
            @Override
            public void run() {
                setChangedAndNotify("buddyconnect:" + connect());
            }

            public boolean connect() {
                L.d("trying to connect to "+super.toString());
                try {
                    rmiClient = new RMIClient(hostname, port);
                    if (rmiClient.checkConnectionAlive()) {
                        setChangedAndNotify("connected");
                        L.d("erfolgreich connected");
                        setStatus(CONNECTIONSTATUS.CONNECTED);
                        return true;
                    } else {
                        return false;
                    }
                } catch (RemoteException ex) {
                    setStatus(CONNECTIONSTATUS.DISCONNECTED);
                    L.n("fehler beim connect, RemoteException" + ex.toString());
                    return false;
                } catch (NotBoundException ex) {
                    setStatus(CONNECTIONSTATUS.DISCONNECTED);
                    L.n("fehler beim connect, NotBoundException:" + ex.toString());
                    return false;
                }
            }

        }.start();
    }
    
    //abkürzung
    private void setChangedAndNotify(Object o) {
        this.setChanged();
        this.notifyObservers(o);
    }

    public String getHostname() {
        return hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
        this.setChangedAndNotify("hostname:" + hostname);
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
        this.setChangedAndNotify("port:" + port);
    }

    public CONNECTIONSTATUS getStatus() {
        if (Status==null) Status=CONNECTIONSTATUS.NULL;
        return Status;
    }

    public void setStatus(CONNECTIONSTATUS Status) {
        this.Status = Status;
        setChangedAndNotify("status");
    }
    
    
    @Override
    public String toString() {
        return "[Buddy " + nickname + "@" + hostname + ":" + port + "]";
    }
    
}
